package lapsnake.core;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Panel;
import java.awt.image.BufferedImage;
import java.util.Queue;



import owg.util.data.Pair;

public class LoadingPanel extends Panel
	{
	private static final long serialVersionUID = -1128424023640118718L;
	
	BufferedImage backBuffer;
	Thread animator;
	volatile long time;
	volatile boolean animate;
	volatile String loadingString;
	
	public LoadingPanel(final LapCore lapCore, Queue<Pair<String, Runnable>> jobs)
		{
		super();
		
		animator = new Thread()
			{
			@Override
			public void run()
				{
				while(animate)
					{
					try{sleep(33);}catch(Exception e){e.printStackTrace();}
					time++;
					repaint();
					}
				}
			};
		time = 0;
		loadingString = "Initializing Loader";
		animate = true;
		animator.start();
		setBackground(Color.BLACK);
		
		Thread glLoader = new Thread() 
			{
			public void run() 
				{
				for(Pair<String, Runnable> job : jobs)
					{
					loadingString = job.a;
					job.b.run();
					}
				java.awt.EventQueue.invokeLater(new Runnable() 
					{
					@Override
					public void run()
						{
						stopAnimation();
						LapCore.loadingCompleted();
						}	
					});
				}
			};
		glLoader.start();

		}
	
	@Override
	public void update(Graphics g)
		{
		//Default behaviour clears background, this causes flicker and it sucks, don't do it please.
		paint(g);
		}
	
	@Override
	public void paint(Graphics g)
		{
		int w = getWidth();
		int h = getHeight();
		
		int imgW = Math.min(256, w);
		int imgH = Math.min(256, h);
		
		if(backBuffer == null || backBuffer.getWidth() != imgW || backBuffer.getHeight() != imgH)
			{
			if(backBuffer != null)
				backBuffer.flush();
			backBuffer = new BufferedImage(imgW, imgH, BufferedImage.TYPE_3BYTE_BGR);
			}
		
		Graphics d = backBuffer.getGraphics();
		
		d.clearRect(0, 0, getWidth(), getHeight());
		d.setColor(Color.decode("#4088A3"));
		
		int nPoints = 9;
		int[] xPoints = new int[nPoints];
		int[] yPoints = new int[nPoints];
		
		
		long q = 12;
		double f = (double)(time%q)/q;
		
		for(int i = 0; i<nPoints-1; i++)
			{
			double a = Math.PI/(nPoints-1)*2*i;
			double r = 80+48*Math.pow(Math.sin(a-f*Math.PI),2);
			xPoints[i] = (int)(imgW/2+r*Math.cos(a));
			yPoints[i] = (int)(imgH/2+r*Math.sin(a));
			}
		xPoints[nPoints-1] = xPoints[0];
		yPoints[nPoints-1] = yPoints[0];
		
		d.drawPolyline(xPoints, yPoints, nPoints);
		int strw = d.getFontMetrics().stringWidth(loadingString);
		int strh = d.getFont().getSize();
		d.drawString(loadingString, imgW/2-strw/2, imgH/2+strh/2);
		d.dispose();
		
		g.clearRect(0, 0, w, h);
		g.drawImage(backBuffer, (w-imgW)/2, (h-imgH)/2, null);
		}

	public void stopAnimation()
		{
		animate = false;
		}
	}
